/**
 * Represents the Transform Weighted Complement Naive Bayes Classifier
 * (TWCNBC)
 * @author alecmgo@gmail.com
  */
public class TWCNBClassifier extends WCNBClassifier {
  public TWCNBClassifier(MessageIterator mi) {
    super(mi);
  }
  
  /**
   * Calculating the conditional probabilities remain the same as in 
   * WCNBClassifier (parent class).  But, the counts are transformed 
   * before these conditional probabilities are calculated.
   */
  void calculateConditionalProbabilities() {
    preprocessCounts();
    super.calculateConditionalProbabilities();
  }
  
  /**
   * Before calculating the conditional probabilities, perform several
   * transforms:
   * <ul>
   * <li>Term-Frequency Transform</li>
   * <li>Inverse Document Frequency Transform</li>
   * <li>Length Normalization Transform</li>
   * </ul>
   */
  void preprocessCounts() {
    for(String term : termCount.keySet()) {
      for(Integer newsgroup : termCount.getCounter(term).keySet()) {
        Double count = termCount.getCount(term, newsgroup);
        
        //Term-Frequency Transform (4.1)
        count = Math.log(count + 1);
        
        //IDF Transform (4.2)
        count = count * Math.log(newsgroupCount.totalCount() / termCount.getCounter(term).size());
        
        termCount.setCount(term, newsgroup, count);
      }
    }
    
    //Length normalization
    for(String term : termCount.keySet()) {
      double lengthDenominator = termCount.getCounter(term).totalCount();
      for(Integer newsgroup : termCount.getCounter(term).keySet()) {
        Double count = termCount.getCount(term, newsgroup);
        
        count = count / lengthDenominator;
        
        termCount.setCount(term, newsgroup, count);
      }
    }    
  }  
}